package com.face.server.repository.exRepository;

import com.face.server.entity.Dormitory;
import com.face.server.entity.Student;
import com.face.server.service.UtileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by ryan on 2018/3/15.
 */
@Repository
public class exDormitoryRepositoryImpl implements exDormitoryRepository {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public List<Dormitory> listDormitories(Pageable pageRequest, String key1, String key2) {
        String[] keys1=new String[]{"dormitoryBuildNum","roomNumber"};
        String  keys2="studentsName";

        Criteria integ=new Criteria();
        ArrayList<Criteria> temp = new ArrayList<>();

        Criteria criteria=new Criteria();
        List<Criteria> criteriaList=new ArrayList<Criteria>();
        Criteria criteria1=new Criteria();
        if (key1!=null&& UtileService.isNum(key1))
            criteria1.orOperator(Arrays.stream(keys1).map(e->Criteria.where(e).is(Integer.parseInt(key1))).toArray(s->new Criteria[s]));
        Criteria criteria2=new Criteria();
        criteria2.where(keys2).regex(key1);
        criteriaList.add(criteria1);criteriaList.add(criteria2);
        criteria.orOperator(criteriaList.stream().toArray(s->new Criteria[s]));
        temp.add(criteria);

        if (key2!=null&&key2.equals("")==false){
            List<Criteria> criList=new ArrayList<Criteria>();
            Criteria cri=new Criteria();
            Criteria cri1=new Criteria();
            if (UtileService.isNum(key2))
                cri1.orOperator(Arrays.stream(keys1).map(e->Criteria.where(e).is(Integer.parseInt(key2))).toArray(s->new Criteria[s]));
            Criteria cri2=new Criteria();
            cri2.where(key2).regex(key2);
            criList.add(cri1);
            criList.add(cri2);
            cri.orOperator(criList.stream().toArray(s->new Criteria[s]));
            temp.add(cri);
        }
        integ.andOperator(temp.stream().toArray(s->new Criteria[s]));

        int page=pageRequest.getPageNumber()>0?pageRequest.getPageNumber()*pageRequest.getPageSize():0;
        Aggregation aggregation=Aggregation.newAggregation(
                Aggregation.match(integ),
                Aggregation.sort(pageRequest.getSort()),
                Aggregation.skip((long)page),
                Aggregation.limit(pageRequest.getPageSize())
        );
        AggregationResults<Dormitory> aggrResult = mongoTemplate.aggregate(aggregation, "dormitory", Dormitory.class);
        return aggrResult.getMappedResults();
    }

    @Override
    public List<Dormitory> listDormitories(Pageable pageRequest, String key1, String key2, List<Integer> dormitoryNumList) {
        String[] keys1=new String[]{"dormitoryBuildNum","roomNumber"};
        String  keys2="studentsName";

        Criteria integ=new Criteria();
        ArrayList<Criteria> temp = new ArrayList<>();

        Criteria c=new Criteria();
        c.and("dormitoryBuildNum").in(dormitoryNumList);
        temp.add(c);

        Criteria criteria=new Criteria();
        List<Criteria> criteriaList=new ArrayList<Criteria>();
        Criteria criteria1=new Criteria();
        if (key1!=null&& UtileService.isNum(key1))
            criteria1.orOperator(Arrays.stream(keys1).map(e->Criteria.where(e).is(Integer.parseInt(key1))).toArray(s->new Criteria[s]));
        Criteria criteria2=new Criteria();
        criteria2.where(keys2).regex(key1);
        criteriaList.add(criteria1);criteriaList.add(criteria2);
        criteria.orOperator(criteriaList.stream().toArray(s->new Criteria[s]));
        temp.add(criteria);

        if (key2!=null&&key2.equals("")==false){
            List<Criteria> criList=new ArrayList<Criteria>();
            Criteria cri=new Criteria();
            Criteria cri1=new Criteria();
            if (UtileService.isNum(key2))
                cri1.orOperator(Arrays.stream(keys1).map(e->Criteria.where(e).is(Integer.parseInt(key2))).toArray(s->new Criteria[s]));
            Criteria cri2=new Criteria();
            cri2.where(key2).regex(key2);
            criList.add(cri1);
            criList.add(cri2);
            cri.orOperator(criList.stream().toArray(s->new Criteria[s]));
            temp.add(cri);
        }
        integ.andOperator(temp.stream().toArray(s->new Criteria[s]));

        int page=pageRequest.getPageNumber()>0?pageRequest.getPageNumber()*pageRequest.getPageSize():0;
        Aggregation aggregation=Aggregation.newAggregation(
                Aggregation.match(integ),
                Aggregation.sort(pageRequest.getSort()),
                Aggregation.skip((long)page),
                Aggregation.limit(pageRequest.getPageSize())
        );
        AggregationResults<Dormitory> aggrResult = mongoTemplate.aggregate(aggregation, "dormitory", Dormitory.class);
        return aggrResult.getMappedResults();
    }
}
